package com.qianbei.common.net.control;

import android.app.Application;
import android.os.Handler;
import android.os.Message;
import android.text.TextUtils;
import android.util.Log;

import com.alibaba.fastjson.JSON;
import com.android.volley.AuthFailureError;
import com.android.volley.NetworkResponse;
import com.android.volley.ParseError;
import com.android.volley.Request.Method;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.Response.ErrorListener;
import com.android.volley.Response.Listener;
import com.android.volley.VolleyError;
import com.android.volley.ext.HttpCallback;
import com.android.volley.ext.RequestInfo;
import com.android.volley.toolbox.HttpHeaderParser;
import com.android.volley.toolbox.MultiPartRequest;
import com.android.volley.toolbox.StringRequest;
import com.google.gson.Gson;
import com.qianbei.common.base.Basebean;
import com.qianbei.common.init.SetData;
import com.qianbei.common.init.SystemConfig;
import com.qianbei.common.log.LoggerInterceptor;
import com.qianbei.common.log.MLog;
import com.qianbei.common.net.control.unlogin.UnloginInterface;
import com.qianbei.common.net.okhttp.RequeastBean;
import com.qianbei.common.net.view.MsgAlert;

import org.json.JSONException;
import org.json.JSONObject;

import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.FormBody;
import okhttp3.Interceptor;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;

public class ServerControl {

    private static final String TAG = "ServerControl";
    private JSONObject sendJson;
    //----------------------------  测试   -----------------------------------
  /*  public static final String URL = "http://122.114.164.162";
    private String url0 = URL + ":14902/";
    public static String url_p_login = ":14901/appLogin.do";//登录
    public static String url_p_logout = ":14901/appLogout.do";//登出*/

    //----------------------------  正式   -----------------------------------
    public static final String URL = "http://192.168.110.168";
    private String url0 = URL + ":82/";
    public static String url_p_login = ":81/appLogin.do";//登录
    public static String url_p_logout = ":81/appLogout.do";

    private String url = url0 + "jsonapi/base/getService.json";                                                 //请求的地址
    private String url1 = url0 + "jsonapi/base/data.json";                                                 //请求的地址
    private String urlImg = url0 + "jsonapi/base/upload.fu";


    public static RequestQueue mQueue;                                  // = Volley.newRequestQueue(BaseApplication.mApplication);;

    private int mMethod = Method.POST;                                  // 默认的请求方式

    private static UnloginInterface unloginListener;                    //如果 接口没有登录，回调去处理 全局配置

    private static Map<String, String> upParams = new HashMap<>();      //网络请求 需要上传的参数


    private Map<String, Object> mPictParams = new HashMap<>();

    Map<String, File> fileParams = new HashMap<>();
    //--------------------okhttp--------------
    private RequeastBean bean;

    static {
        SystemConfig sc = SystemConfig.getInstance();
        upParams.put("mobile_type", sc.os);
        upParams.put("app_version", sc.version);
        upParams.put("device_name", sc.device_name);
        upParams.put("network_type", sc.network_type);
        upParams.put("device_version", sc.device_system_version);
        upParams.put("device_id", sc.getAppID());


    }

    public ServerControl() {
    }

    public ServerControl(String ul, Map<String, Object> upParams) {
        url = ul;
        this.mPictParams = upParams;
    }

    public ServerControl(Map<String, File> fileParams) {
        this.fileParams = fileParams;
    }

    public ServerControl(String ul, Object... key_value) {
        url = ul;
        this.sendJson = createSendJson(key_value);
    }


    public ServerControl(RequeastBean mbean) {
//        this.sendJson = createSendJson(key_value);
        bean = mbean;
        //new RequeastBean(serviceMethod,serviceName,b);


//        bean= new RequeastBean(serviceMethod, serviceName, sendJson);
    }

    public ServerControl(int method, String ul, Object... key_value) {
        mMethod = method;
        url = ul;
        this.sendJson = createSendJson(key_value);
    }

    public ServerControl(int method, String ul, JSONObject obj) {
        mMethod = method;
        url = ul;
        this.sendJson = obj;
    }

    public ServerControl(int method, String ul, String json) {
        try {
            JSONObject myJsonObject = new JSONObject(json);
            mMethod = method;
            url = ul;
            this.sendJson = myJsonObject;
        } catch (JSONException e) {
            e.printStackTrace();
        }

    }

    public static JSONObject createSendJson(Object... key_value) {

        JSONObject bodyJson = new JSONObject();

        for (int i = 0; i < key_value.length - 1; i++) {
            if (i % 2 == 0) {
                try {
                    if (key_value[i + 1] != null) {
                        bodyJson.put(key_value[i].toString(),
                                key_value[i + 1].toString());
//                        MLog.dLog("key=" + key_value[i].toString() +
//                                "-------value======" + key_value[i + 1].toString());
                    } else {
                        bodyJson.put(key_value[i].toString(), "");
                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
        }

        return bodyJson;
    }

    /**
     * 启动客户端与服务端通信流程
     */

    public void startVolley() {
        if (mMethod == Method.GET) {
            SystemConfig sc = SystemConfig.getInstance();
            Map<String, String> params = (Map<String, String>) JSON
                    .parse(sendJson.toString());
            params.putAll(upParams);

            StringBuffer temParamString = new StringBuffer();

            for (Map.Entry<String, String> entry : params.entrySet()) {
                temParamString.append(entry.getKey() + "=" + entry.getValue() + "&");
            }
            url = url + temParamString;
        } else if (mMethod == Method.DELETE && sendJson.length() > 0) {
            Map<String, String> params = (Map<String, String>) JSON
                    .parse(sendJson.toString());
            params.putAll(upParams);

            String paramStr = prepareParam(params);
            url += "?" + paramStr;
        } else if (mMethod == Method.POST && sendJson.length() > 0) {
            Map<String, String> params = (Map<String, String>) JSON
                    .parse(sendJson.toString());
            String paramStr = prepareParam(params);
            url += "?" + paramStr;
        }
        volleyRequeset(url, mMethod);
    }

    private void volleyRequeset(final String url, int method) {
        Log.d("总接口startVolley", "url:" + url);
        Log.d("总接口startVolley", "参数:" + sendJson.toString());
        StringRequest stringRequest = new StringRequest(method, url,
                new SuccessListener(), new ErrListener()) {
            @Override
            protected Map<String, String> getParams() {
                // 在这里设置需要post的参数
                Map<String, String> params = (Map<String, String>) JSON
                        .parse(sendJson.toString());
                params.putAll(upParams);
                return params;
            }

            /**
             * 设置上传cookie
             */
            @Override
            public Map<String, String> getHeaders() throws AuthFailureError {
                HashMap map = new HashMap();
                SystemConfig sc = SystemConfig.getInstance();
                map.put("Cookie", sc.getCooke());
                String token = SetData.getToken();
                if (!TextUtils.isEmpty(token)) {
                    map.put("token", token);
                }
                return map;
            }

            /**
             * 获取 请求完的cookie
             */
            @Override
            protected Response<String> parseNetworkResponse(
                    NetworkResponse response) {
                try {
                    Map<String, String> responseHeaders = response.headers;
                    String rawCookies = responseHeaders.get("Set-Cookie");
                    if (url.equals(Constant.USER_LOGIN)
                            || url.equals(Constant.USER_REGISTER) || url.equals(Constant.OAUTH_SIGNIN_URL)) {
                        SystemConfig.getInstance().setCooke(rawCookies);
                    }

                    String dataStr = new String(response.data, "UTF-8");
                    Log.d("总接口startVolley", "总返回:" + dataStr);

                    return Response.success(dataStr,
                            HttpHeaderParser.parseCacheHeaders(response));
                } catch (UnsupportedEncodingException e) {
                    return Response.error(new ParseError(e));
                }
            }
        };

        stringRequest.setTag(this);
        mQueue.add(stringRequest);
        // mQueue.start();
    }


    /**
     * 上传图片
     */
    public void upLoadImage() {


//        Map<String, Object> params = new HashMap<String, Object>();

//        if (imgData != null) {
//            params.put("file", new File(imgData));
//        }
        RequestInfo requestInfo = new RequestInfo();
        requestInfo.url = url;
        requestInfo.putAllParams(mPictParams);
        upload(requestInfo, new HttpCall());
//        upDialog.showProgress("正在上传");
    }


    /**
     * upload 请求
     *
     * @param requestInfo
     * @param httpResult
     */
    public void upload(final RequestInfo requestInfo,
                       final HttpCallback httpResult) {
        final String url = requestInfo.getUrl();
        if (TextUtils.isEmpty(url)) {
            if (httpResult != null) {
                httpResult.onStart();
                httpResult.onError(new Exception("url can not be empty!"));
                httpResult.onFinish();
            }
            return;
        }
        final Map<String, String> paramsMap = requestInfo.getParams();
        final Map<String, File> fileParams = requestInfo.getFileParams();
//        VolleyLog.d("upload->%s\t,file->%s\t,form->%s", url, fileParams,
//                paramsMap);
        if (httpResult != null) {
            httpResult.onStart();
        }
        MultiPartRequest<String> request = new MultiPartRequest<String>(
                Method.POST, url, new Listener<String>() {

            @Override
            public void onResponse(String response) {
                if (httpResult != null) {
                    httpResult.onResult(response);
                    httpResult.onFinish();
                }
            }
        }, new ErrorListener() {

            @Override
            public void onErrorResponse(VolleyError error) {
                if (httpResult != null) {
                    httpResult.onError(error);
                    httpResult.onFinish();
                }
            }
        }, new Response.LoadingListener() {

            @Override
            public void onLoading(long count, long current) {
                if (httpResult != null) {
                    httpResult.onLoading(count, current);
                }
            }
        }) {

            /**
             * 设置上传cookie
             */
            @Override
            public Map<String, String> getHeaders() throws AuthFailureError {
                HashMap localHashMap = new HashMap();
//				MLog.dLog("上传的cooke:"+sc.getCooke());
                localHashMap.put("Cookie", SystemConfig.getInstance().getCooke());
                return localHashMap;
            }


            @Override
            public void cancel() {
                super.cancel();
                if (httpResult != null) {
                    httpResult.onCancelled();
                }
            }

            /**
             * 获取 请求完的cookie
             */
            @Override
            protected Response<String> parseNetworkResponse(
                    NetworkResponse response) {
                try {
                    Map<String, String> responseHeaders = response.headers;
                    String rawCookies = responseHeaders.get("Set-Cookie");
                    // SystemConfig sc = BaseApplication.sConfig;
                    // sc.setCooke(rawCookies);
//					MLog.dLog("下来的的cooke:"+rawCookies);
                    String dataString = new String(response.data, "UTF-8");
                    return Response.success(dataString,
                            HttpHeaderParser.parseCacheHeaders(response));
                } catch (UnsupportedEncodingException e) {
                    return Response.error(new ParseError(e));
                }
            }

        };

        if (paramsMap != null && paramsMap.size() != 0) {
            for (Map.Entry<String, String> entry : paramsMap.entrySet()) {
                request.addPart(entry.getKey(), entry.getValue());

                MLog.dLog("key=" + entry.getKey() + "**value="
                        + entry.getValue());
            }
        }
        if (fileParams != null && fileParams.size() != 0) {
            for (Map.Entry<String, File> entry : fileParams.entrySet()) {
                String key = entry.getKey();
                int index = key.indexOf(requestInfo.boundary);
                if (index > 0) {
                    key = key.substring(0, index);
                }
                request.addPart(key, entry.getValue());
            }
        }
        request.setTag(this);
        mQueue.add(request);
    }

    private ServerResult parseData(String receiveData) throws Exception {
        ServerResult sr = new ServerResult();
        // 生成json数据
        JSONObject jsonData = new JSONObject(receiveData);
        sr.bodyData = jsonData;
        String code = jsonData.optString("code");
        if (code != null) {
            if (code.equals("100001")) {
                sr.isLogin = true;
                if (unloginListener != null) {
                    unloginListener.unloginlistener();
                }
            } else {
                sr.isContinue = code.equals("0");
                sr.isLogin = false;
                if (code.equals("100003")) {
                    sr.resultCode = code;
                }
            }
        } else {
            sr.exception = new Exception("code2 = null");
        }
        return sr;
    }

    class ErrListener implements ErrorListener {

        @Override
        public void onErrorResponse(VolleyError e) {

//			MLog.dLog("VolleyError=" + e.toString());
            ServerResult sr = new ServerResult();
            Message msg = new Message();
            msg.what = 0;
            sr.exception = e;
            msg.obj = sr;
            serverHandler.sendMessage(msg);
        }

    }

    class SuccessListener implements Listener<String> {

        @Override
        public void onResponse(String arg0) {

//			MLog.dLog(arg0);
            ServerResult sr = new ServerResult();
            try {
                sr = parseData(arg0);
            } catch (Exception e) {
                e.printStackTrace();
            }
            Message msg = new Message();
            msg.what = 0;
            msg.obj = sr;
            serverHandler.sendMessage(msg);
        }

    }

    /**
     * @param ul
     * @param bodyJson
     * @return
     */

    Handler serverHandler = new Handler() {

        boolean isShowNetBreak = false;

        public void handleMessage(Message msg) {
            switch (msg.what) {
                case 0:
                    // 如果UI对象已释放，将不再回调
                    ServerResult sr = (ServerResult) msg.obj;

//				MLog.dLog("response:="+sr.bodyData.toString());
                    if (serverListener != null) {
                        try {
                            serverListener.serverFinish(sr);
                            // parseMsg.parseMsg(sr.bodyData.optJSONObject("msg2"));
                        } catch (Exception e) {
                            sr.exception = e;
//                            serverListener.serverFinish(sr);
                        }
                    }

                    /******************** 有网络报错提示网络报错 各个接口不不需要写 特殊情况 自己判断处理 ***********/
                    if (sr.exception != null) {
                        if (isShowNetBreak) {
                            new MsgAlert().show("网络断了吗,请再重新加载一次吧！");
                            isShowNetBreak = false;
                            this.postDelayed(new Runnable() {
                                @Override
                                public void run() {
                                    isShowNetBreak = true;
                                }
                            }, 10000);
                        }

                        sr.exception.printStackTrace();
                        return;
                    }
                    if (!sr.isContinue) {
                        if (sr != null && sr.bodyData != null
                                && !TextUtils.isEmpty(sr.bodyData.optString("message"))) {
                            new MsgAlert().show(sr.bodyData.optString("message"));
                        }

                    }
                    /******************** 有网络报错提示网络报错 ***********/
                    break;

                case 1:
                    if (progressListener != null) {
                        progressListener.progressRate(msg.arg1);
                    }
                    break;
            }
        }

        ;
    };

    public ServerListener serverListener;

    public interface ServerListener {
        public void serverFinish(ServerResult sr);
    }

    public ProgressListener progressListener;

    public interface ProgressListener {
        public void progressRate(int value);
    }


    public static void setUnloginListener(UnloginInterface temInterface) {
        unloginListener = temInterface;
    }

    private String prepareParam(Map<String, String> paramMap) {
        StringBuffer sb = new StringBuffer();
        if (paramMap.isEmpty()) {
            return "";
        } else {
            for (String key : paramMap.keySet()) {
                String value = paramMap.get(key);
                if (sb.length() < 1) {
                    sb.append(key).append("=").append(value);
                } else {
                    sb.append("&").append(key).append("=").append(value);
                }
            }
            return sb.toString();
        }
    }

    /**
     * 图片请求的回调 集中处理
     */

    class HttpCall implements HttpCallback {

//        private int id;
//        private String path;
//
//
//        public HttpCall(String path, int id) {
//            this.id = id;
//            this.path = path;
//        }

        public HttpCall() {
        }

        @Override
        public void onStart() {

        }

        @Override
        public void onResult(String string) {
            ServerResult sr = new ServerResult();
            try {
                sr = parseData(string);
            } catch (Exception e) {
                e.printStackTrace();
            }
            Message msg = new Message();
            msg.what = 0;
            msg.obj = sr;
            serverHandler.sendMessage(msg);
        }

        @Override
        public void onLoading(long count, long current) {

        }

        @Override
        public void onFinish() {

        }

        @Override
        public void onError(Exception e) {
            ServerResult sr = new ServerResult();
            Message msg = new Message();
            msg.what = 0;
            sr.exception = e;
            msg.obj = sr;
            serverHandler.sendMessage(msg);
        }

        @Override
        public void onCancelled() {

        }

    }

    public static final MediaType FORM_CONTENT_TYPE
            = MediaType.parse("application/x-www-form-urlencoded; charset=utf-8");

    public void OKpost() {
        OkHttpClient okHttpClient = new OkHttpClient.Builder()
                .connectTimeout(100, TimeUnit.SECONDS)
                .writeTimeout(100, TimeUnit.SECONDS)
                .readTimeout(200, TimeUnit.SECONDS)
                .addInterceptor(new LoggerInterceptor(TAG, true))
                .addInterceptor(new Interceptor() {
                    @Override
                    public okhttp3.Response intercept(Chain chain) throws IOException {
                        Request request = chain.request()
                                .newBuilder()
                                .addHeader("token", SetData.getToken())
                                .addHeader(SetData.clientType, SetData.Android)
                                .build();
                        return chain.proceed(request);
                    }

                })
                .build();

        Gson gson = new Gson();
        String json = gson.toJson(bean);

        RequestBody requestBody = RequestBody.create(FORM_CONTENT_TYPE, "data=" + json);
        Request request = new Request.Builder()
                .url(url)//请求的url
                .post(requestBody)
                .build();

        Log.d("总接口post", "地址:" + url);
        Log.d("总接口post", "参数:" + json);
        Call call = okHttpClient.newCall(request);
        call.enqueue(new Calls());
    }

    public String getUrl() {
        return url;
    }

    public String getUrlImg() {
        return urlImg;
    }

    public void OKpost1() {
        OkHttpClient okHttpClient = new OkHttpClient.Builder()
                .connectTimeout(100, TimeUnit.SECONDS)
                .writeTimeout(100, TimeUnit.SECONDS)
                .readTimeout(200, TimeUnit.SECONDS)
                .addInterceptor(new LoggerInterceptor(TAG, true))
                .addInterceptor(new Interceptor() {
                    @Override
                    public okhttp3.Response intercept(Chain chain) throws IOException {
                        Request request = chain.request()
                                .newBuilder()
                                .addHeader("token", SetData.getToken())
                                .addHeader(SetData.clientType, SetData.Android)
                                .build();
                        return chain.proceed(request);
                    }

                })
                .build();

        Gson gson = new Gson();
        String json = gson.toJson(bean);
        RequestBody requestBody = RequestBody.create(FORM_CONTENT_TYPE, "data=" + json);
        Log.d("总接口post1", "地址:" + url);
        Log.d("总接口post1", "参数:" + json);
        Request request = new Request.Builder()
                .url(url1)
                .post(requestBody)
                .build();

        Call call = okHttpClient.newCall(request);
        call.enqueue(new Calls());
    }

    public void OKpost1_url() {
        OkHttpClient okHttpClient = new OkHttpClient.Builder()
                .connectTimeout(100, TimeUnit.SECONDS)
                .writeTimeout(100, TimeUnit.SECONDS)
                .readTimeout(200, TimeUnit.SECONDS)
                .addInterceptor(new LoggerInterceptor(TAG, true))
                .addInterceptor(new Interceptor() {
                    @Override
                    public okhttp3.Response intercept(Chain chain) throws IOException {
                        Request request = chain.request()
                                .newBuilder()
                                .addHeader("token", SetData.getToken())
                                .addHeader(SetData.clientType, SetData.Android)
                                .build();
                        return chain.proceed(request);
                    }

                })
                .build();

        Gson gson = new Gson();
        String json = gson.toJson(bean);

        RequestBody requestBody = RequestBody.create(FORM_CONTENT_TYPE, "data=" + json);
        Request request = new Request.Builder()
                .url(url1)
                .post(requestBody)
                .build();

        Call call = okHttpClient.newCall(request);
        call.enqueue(new Calls());
    }

    public void OKpost2() {
        OkHttpClient okHttpClient = new OkHttpClient.Builder()
                .connectTimeout(100, TimeUnit.SECONDS)
                .writeTimeout(100, TimeUnit.SECONDS)
                .readTimeout(200, TimeUnit.SECONDS)
                .addInterceptor(new LoggerInterceptor(TAG))
                .addInterceptor(new Interceptor() {
                    @Override
                    public okhttp3.Response intercept(Chain chain) throws IOException {
                        Request request = chain.request()
                                .newBuilder()
                                .addHeader("token", SetData.getToken())
                                .addHeader(SetData.clientType, SetData.Android)
                                .build();
                        return chain.proceed(request);
                    }

                })
                .build();

        Gson gson = new Gson();
        String json = gson.toJson(bean);
        RequestBody requestBody = RequestBody.create(FORM_CONTENT_TYPE, "data=" + json);
        Request request = new Request.Builder()
                .url(url)//请求的url
                .post(requestBody)
                .build();
        Call call = okHttpClient.newCall(request);
        call.enqueue(null);
    }

    /**
     * 上传图片
     * 参数为要上传的网址，本地照片在本地的地址，我们自己定义的接口
     */

    public void OkhttpUpLoadImage() {
        OkHttpClient client = new OkHttpClient.Builder()
                .connectTimeout(100, TimeUnit.SECONDS)
                .writeTimeout(100, TimeUnit.SECONDS)
                .readTimeout(200, TimeUnit.SECONDS)
                .addInterceptor(new LoggerInterceptor(TAG))
                .addInterceptor(new Interceptor() {
                    @Override
                    public okhttp3.Response intercept(Chain chain) throws IOException {
                        Request request = chain.request()
                                .newBuilder()
                                .addHeader("token", SetData.getToken())
                                .addHeader(SetData.clientType, SetData.Android)
                                .build();
                        return chain.proceed(request);
                    }

                })
                .build();


        //OkHttpClient作为全局静态变量已经定义过了
        //2.创建一个请求体
        RequestBody body;
        //3.创建一个请求体建造器
        MultipartBody.Builder builder = new MultipartBody.Builder().setType(MultipartBody.FORM);


        if (fileParams != null && fileParams.size() != 0) {
            for (Map.Entry<String, File> entry : fileParams.entrySet()) {
                String key = entry.getKey();
                builder.addFormDataPart(key, entry.getValue().getName(), RequestBody.create(MediaType.parse("image/jpg"),
                        entry.getValue()));

            }
        }


        body = builder.build();

        //3.创建一个请求，利用构建器方式添加url和请求体。
        Request request = new Request.Builder().post(body).url(urlImg).build();

        //4.定义一个call，利用okhttpclient的newcall方法来创建对象。因为Call是一个接口不能利用构造器实例化。
        Call call = client.newCall(request);

        //5.这是异步调度方法，上传和接受的工作都在子线程里面运作，如果要使用同步的方法就用call.excute(),此方法返回的就是Response
        call.enqueue(new Calls());
    }


    class Calls implements Callback {
        //请求错误回调方法
        @Override
        public void onFailure(Call call, IOException e) {
            ServerResult sr = new ServerResult();
            Message msg = new Message();
            msg.what = 0;
            sr.exception = e;
            msg.obj = sr;
            serverHandler.sendMessage(msg);
        }

        @Override
        public void onResponse(Call call, okhttp3.Response response) throws IOException {
            ServerResult sr = new ServerResult();
            try {
                sr = parseData(response.body().string());
            } catch (Exception e) {
                e.printStackTrace();
            }
            Message msg = new Message();
            msg.what = 0;
            msg.obj = sr;
            serverHandler.sendMessage(msg);
        }
    }

}
